package com.prs.crm.ftp.server;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Security;
import java.util.ArrayList;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/** 
 * <p>Copyright: Copyright (c) 2012</p>
 * @author JohnLan 
 * E-mail:JohnMr.Lan@foxmail.com 
 * @version 创建时间：2012-6-27 下午04:26:17 
 * 
 * 类说明 
 */

public class DES {

	  //远程接口
	//  private documentModel RemoteInterface = DocSql.getInstance().getDocumentModel();
	  //加密和解密的钥匙
	  private byte[] EncodAndDecodeKey = null;
	  //加解密算法
	  private static String strAlgorithm = "DESede";

	  public DES() {
	    try { ///
	      ///密钥读入---------------------------------------------------------------
	      String sql = "select CKeyStr from " ;
	      ArrayList rsList = new ArrayList();
	      if (rsList == null || rsList.size() < 1) {
	        return;
	      }
	      String str = String.valueOf(rsList.get(0));
	      int size = str.length();
	      byte[] temKey = str.getBytes();
	      EncodAndDecodeKey = new byte[size];
	      for (int i = 0; i < size; i++) {
	        EncodAndDecodeKey[i] = temKey[i];
	      }
	    }
	    catch (Exception ex) {
	      ex.printStackTrace();
	    }
	  }

	//  public void GenerateKey() {
//	    try {
//	      //加入SunJCE provider
//	      Security.addProvider(new com.sun.crypto.provider.SunJCE());
//	      //密钥生成器
//	      KeyGenerator KeyGen = KeyGenerator.getInstance("DESede");
//	      //密钥
//	      SecretKey theKey = KeyGen.generateKey();
//	      //密钥字节码
	//
//	      //要保存的数据keyencoded
//	      byte[] keyencoded = theKey.getEncoded();
//	      String keyStr = "";
//	      for (int i = 0; i < keyencoded.length; i++) {
//	        keyStr += (char) keyencoded[i];
//	      }
//	      this.RemoteInterface.executeSql("delete from " + TableName.SYS_DES);
//	      String sql = "Insert into " + TableName.SYS_DES + "(CKeyStr) values('" +
//	          keyStr + "')";
//	      this.RemoteInterface.executeSql(sql);
//	    }
//	    catch (Exception ex) {
//	      ex.printStackTrace();
//	    }
	//  }

	  //------------------------------------
	  //密钥生成函数 GenerateKey
	  //输入参数:
	  //   strKeyFile: 密钥保存文件(将被创建)
	  //------------------------------------
	  public void GenerateKey(String strKeyFile) {
	    try {

	      //加入SunJCE provider
	      Security.addProvider(new com.sun.crypto.provider.SunJCE());
	      //密钥生成器
	      KeyGenerator KeyGen = KeyGenerator.getInstance("DESede");
	      //密钥
	      SecretKey theKey = KeyGen.generateKey();
	      //密钥字节码

	      //要保存的数据keyencoded
	      byte[] keyencoded = theKey.getEncoded();

	      int keylen = keyencoded.length;

	      FileOutputStream outkey = new FileOutputStream(strKeyFile);
	      outkey.write(keylen);
	      outkey.write(keyencoded);
	      outkey.close();

	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	    }
	    catch (java.io.IOException e2) {
	      e2.printStackTrace();
	    }

	  }

	  //----------------------------------
	  //文件加密函数 EncryptData
	  //输入参数:
	  //  strSourceFile:明文文件
	  //  strEnDataFile:密文文件(将被创建)
	  //  strKeyFile:   密钥文件
	  //----------------------------------

	  public void EncryptData(String strSourceFile, String strEnDataFile,
	                          String strKeyFile) {

	    try {

	      ///密钥读入----------------------------------------------------------------
	      FileInputStream inkey = new FileInputStream(strKeyFile);
	      int keylen = inkey.read();
	      byte[] keyencoded = new byte[keylen];
	      inkey.read(keyencoded);

	      javax.crypto.spec.SecretKeySpec destmp = new javax.crypto.spec.
	          SecretKeySpec(keyencoded, "DESede");
	      SecretKey theKey = destmp;
	      ///-----------------------------------------------------------------------

	      ///加密系统初始化-----------------------------------------------------------

	      //初始化向量
	      IvParameterSpec ivp = new IvParameterSpec(new byte[] {12, 34, 56, 78, 90,
	                                                87, 65, 43});

	      //生成特定类型密码器
	      Cipher cipher = Cipher.getInstance("DESede");

	      //初始化密码器
	      cipher.init(Cipher.ENCRYPT_MODE, theKey, ivp);

	      ///------------------------------------------------------------------------
	      FileInputStream in = new FileInputStream(strSourceFile);
	      FileOutputStream out = new FileOutputStream(strEnDataFile);

	      ///加密--------------------------------------------------------------------

	      byte[] Data = new byte[128];
	      int bytes = 0;
	      while ( (bytes = in.read(Data)) > 0) {
	        if (bytes == 128) {
	          byte[] encryptedtext = cipher.doFinal(Data);
	          int len = encryptedtext.length;
	          out.write(len);
	          out.write(encryptedtext);
	        }
	        else {
	          byte[] DataEnd = new byte[bytes];
	          //for(int i=0;i<bytes;i++)DataEnd[i]=Data[i];
	          System.arraycopy(Data, 0, DataEnd, 0, bytes);
	          byte[] encryptedtext = cipher.doFinal(DataEnd);
	          int len = encryptedtext.length;
	          out.write(len);
	          out.write(encryptedtext);
	        }
	      }

	      ///------------------------------------------------------------------------

	      in.close();
	      out.close();

	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {
	      e2.printStackTrace();
	    }
	    catch (java.lang.Exception e3) {
	      e3.printStackTrace();
	    }
	    catch (java.lang.NoSuchMethodError e4) {
	      e4.printStackTrace();
	    }
	  }

	  //----------------------------------
	  //文件加密函数 EncryptData
	  //输入参数:
	  //  strSourceFile:明文文件
	  //  strEnDataFile:密文文件(将被创建)
	  //modified by yangbo 2003.5.15
	  //----------------------------------
	  public boolean EncryptData(String strSourceFile, String strEnDataFile) {
	    try {
	      ///密钥读入---------------------------------------------------------------
	      SecretKeySpec destmp = new SecretKeySpec(EncodAndDecodeKey, "DESede");
	      SecretKey theKey = destmp;
	      ///-----------------------------------------------------------------------
	      ///加密系统初始化-----------------------------------------------------------

	      //初始化向量
//	      IvParameterSpec ivp = new IvParameterSpec(new byte[] {12, 34, 56, 78, 90,
//	                                                87, 65, 43});

	      //生成特定类型密码器
	      Cipher cipher = Cipher.getInstance("DESede");

	      //初始化密码器
	      cipher.init(Cipher.ENCRYPT_MODE, theKey) /*, ivp)*/;

	      ///------------------------------------------------------------------------
	      FileInputStream in = new FileInputStream(strSourceFile);
	      FileOutputStream out = new FileOutputStream(strEnDataFile);

	      ///加密--------------------------------------------------------------------

	      byte[] Data = new byte[240];
	      int bytes = 0;
	      while ( (bytes = in.read(Data)) > 0) {
	        if (bytes == 240) {
	          byte[] encryptedtext = cipher.doFinal(Data);
	          int len = encryptedtext.length;
	          out.write(len);
	          out.write(encryptedtext);
	        }
	        else {
	          byte[] DataEnd = new byte[bytes];
	          //for(int i=0;i<bytes;i++)DataEnd[i]=Data[i];
	          System.arraycopy(Data, 0, DataEnd, 0, bytes);
	          byte[] encryptedtext = cipher.doFinal(DataEnd);
	          int len = encryptedtext.length;
	          out.write(len);
	          out.write(encryptedtext);
	        }
	      }

	      ///------------------------------------------------------------------------

	      in.close();
	      out.close();
	      return true;
	    }
	    catch (java.io.FileNotFoundException fnfex) {
	      System.out.println("系统找不到指定的文件");

	    }
	    catch (java.security.NoSuchAlgorithmException e1) {

	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {

	    }
	    catch (java.lang.Exception e3) {

	    }
	    catch (java.lang.NoSuchMethodError e4) {

	    }
	    return false;
	  }

	  //----------------------------------
	  //文件解密函数 DecryptData
	  //输入参数:
	  //  strEnDataFile:密文文件
	  //  strDeDataFile:解密文件(将被创建)
	  //  strKeyFile:   密钥文件
	  //----------------------------------

	  public void DecryptData(String strEnDataFile, String strDeDataFile,
	                          String strKeyFile) {
	    try {
	      //密钥读入----------------------------------------------------------------
	      FileInputStream inkey = new FileInputStream(strKeyFile);
	      int keylen = inkey.read();
	      byte[] keyencoded = new byte[keylen];
	      inkey.read(keyencoded);
	      javax.crypto.spec.SecretKeySpec destmp = new javax.crypto.spec.
	          SecretKeySpec(keyencoded, "DESede");
	      SecretKey theKey = destmp;
	      ///------------------------------------------------------------------------
	      //初始化向量
	      IvParameterSpec ivp = new IvParameterSpec(new byte[] {12, 34, 56, 78, 90,
	                                                87, 65, 43});
	      //生成特定类型密码器
	      Cipher cipher = Cipher.getInstance("DESede");
	      //初始化密码器
	      cipher.init(Cipher.DECRYPT_MODE, theKey, ivp);
	      FileInputStream in = new FileInputStream(strEnDataFile);
	      FileOutputStream out = new FileOutputStream(strDeDataFile);
	      ///解密--------------------------------------------------------------------
	      int len;
	      while ( (len = in.read()) > 0) {
	        byte[] Data = new byte[len];
	        in.read(Data);
	        byte[] decryptedtext = cipher.doFinal(Data);
	        out.write(decryptedtext);
	      }

	      ///------------------------------------------------------------------------

	      in.close();
	      out.close();
	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {
	      e2.printStackTrace();
	    }
	    catch (java.lang.Exception e3) {
	      e3.printStackTrace();
	    }
	    catch (java.lang.NoSuchMethodError e4) {
	      e4.printStackTrace();
	    }
	  }

	  //----------------------------------
	  //文件解密函数 DecryptData
	  //输入参数:
	  //  strEnDataFile:密文文件
	  //  strDeDataFile:解密文件(将被创建)
	  //----------------------------------

	  public void DecryptData(String strEnDataFile, String strDeDataFile) {
	    try {
	      ///密钥读入---------------------------------------------------------------
	      SecretKeySpec destmp = new SecretKeySpec(EncodAndDecodeKey, "DESede");
	      SecretKey theKey = destmp;
	      ///------------------------------------------------------------------------
//	      //初始化向量
//	      IvParameterSpec ivp = new IvParameterSpec(new byte[] {12, 34, 56, 78, 90,
//	                                                87, 65, 43});
	      //生成特定类型密码器
	      Cipher cipher = Cipher.getInstance("DESede");
	      //初始化密码器
	      cipher.init(Cipher.DECRYPT_MODE, theKey); //, ivp);
	      FileInputStream in = new FileInputStream(strEnDataFile);
	      FileOutputStream out = new FileOutputStream(strDeDataFile);
	      ///解密--------------------------------------------------------------------
	      //long l1 = System.currentTimeMillis();
	      int len;
	      while ( (len = in.read()) > 0) {
	        byte[] Data = new byte[len];
	        in.read(Data);
	        byte[] decryptedtext = cipher.doFinal(Data);
	        out.write(decryptedtext);
	      }
	      //System.out.println(System.currentTimeMillis() - l1);
	      ///------------------------------------------------------------------------
	      in.close();
	      out.close();
	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {
	      e2.printStackTrace();
	    }
	    catch (java.lang.Exception e3) {
	      e3.printStackTrace();
	    }
	    catch (java.lang.NoSuchMethodError e4) {
	      e4.printStackTrace();
	    }
	  }

	  //加密
	  public static String EncryptString(String strSource) {
	    if (strSource == null) {
	      return null;
	    }
	    String strKey = "??Qb1?????????C???Qb1???";
	    int size = strKey.length();
	    byte[] temKey = strKey.getBytes();
	    byte[] EncodAndDecodeKey = new byte[size];
	    for (int i = 0; i < size; i++) {
	      EncodAndDecodeKey[i] = temKey[i];
	    }

	    Security.addProvider(new com.sun.crypto.provider.SunJCE());
	    try {
	      SecretKeySpec tmpkey = new SecretKeySpec(EncodAndDecodeKey, strAlgorithm);
	      SecretKey deskey = tmpkey;

	      Cipher c1 = Cipher.getInstance(strAlgorithm);
	      c1.init(Cipher.ENCRYPT_MODE, deskey);
	      byte[] cipherByte = c1.doFinal(strSource.getBytes());

	      //将字节码转换为字符串，不能用new String(cipherByte)方法.
//	      String strEncrypt = "";
//	      for (int i = 0; i < cipherByte.length; i++) {
//	        strEncrypt += (char) cipherByte[i];
//	      }
	      String strEncrypt = "";
	      String strTest = "";
	      for (int i = 0; i < cipherByte.length; i++) {
	        if (i != cipherByte.length - 1) {
	          strEncrypt = strEncrypt + cipherByte[i] + ",";
	        }
	        else {
	          strEncrypt = strEncrypt + cipherByte[i];
	        }
	      }

	      return strEncrypt;
	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	      return null;
	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {
	      e2.printStackTrace();
	      return null;
	    }
	    catch (java.lang.Exception e3) {
	      e3.printStackTrace();
	      return null;
	    }
	  }

	  /*******************************************************
	   * 价格解密算法有问题
	   *******************************************************/
	  public static String DecryptString(String strEncrypt) {
	    if (strEncrypt == null || strEncrypt.equals("")) {
	      return "";
	    }
	    String strKey = "??Qb1?????????C???Qb1???";
	    int size = strKey.length();
	    byte[] temKey = strKey.getBytes();
	    byte[] EncodAndDecodeKey = new byte[size];
	    for (int i = 0; i < size; i++) {
	      EncodAndDecodeKey[i] = temKey[i];
	    }

	    Security.addProvider(new com.sun.crypto.provider.SunJCE());
	    try {
	      SecretKeySpec tmpkey = new SecretKeySpec(EncodAndDecodeKey, strAlgorithm);
	      SecretKey deskey = tmpkey;

//	      ///解密--------------------------------------------------------------------
//	      String strDeData = cipher.doFinal(strEnData.getBytes()).toString();
//	      return strDeData;

	      Cipher c1 = Cipher.getInstance(strAlgorithm);
	      c1 = Cipher.getInstance(strAlgorithm);
	      c1.init(Cipher.DECRYPT_MODE, deskey);

	      /* !将字符串转换为字节，不能用strEncrypt.getbytes()方法*/
//	      byte bEncrypt[] = new byte[strEncrypt.length()];
//	      for (int i = 0; i < strEncrypt.length(); i++) {
//	        char c = strEncrypt.charAt(i);
//	        bEncrypt[i] = (byte) c;
//	      }
	      ArrayList altGetBytes = new ArrayList();
//	      byte bEncrypt[] = new byte[strEncrypt.length()];
	      for (int i = 0; i < strEncrypt.length(); i++) {
	        int iStart = i;
	        i = strEncrypt.indexOf(",", i);
	        if (i < 0 || i >= strEncrypt.length()) {
	          i = strEncrypt.length();
	        }
	        String strGetedByte = strEncrypt.substring(iStart, i);
	        altGetBytes.add(strGetedByte);
	      }
	      byte[] bEncrypt = new byte[altGetBytes.size()];
	      for (int i = 0; i < altGetBytes.size(); i++) {
	        try {
	          int ii = Integer.valueOf(altGetBytes.get(i).toString()).intValue();
	          bEncrypt[i] = (byte) ii;
	        }
	        catch (Exception ex) {
	          return strEncrypt;
	        }
	      }
	      byte[] cipherByte = c1.doFinal(bEncrypt);
	      String strDecrypt = new String(cipherByte);
	      return strDecrypt;
	    }
	    catch (java.security.NoSuchAlgorithmException e1) {
	      e1.printStackTrace();
	      return null;
	    }
	    catch (javax.crypto.NoSuchPaddingException e2) {
	      e2.printStackTrace();
	      return null;
	    }
	    catch (java.lang.Exception e3) {
	      e3.printStackTrace();
	      return null;
	    }
	    catch (java.lang.NoSuchMethodError e4) {
	      e4.printStackTrace();
	      return null;
	    }
	  }
}
